"""
分页组件

使用说明：
1. 在视图文件：
def customer_list(request):
    queryset = Customer.objects.filter(active=True).select_related('level').order_by('id')

    from utils.pager import Pagination
    pager = Pagination(request, queryset)

    customer = {
        'queryset': queryset[pager.item_start:pager.item_end],
        'page_html': pager.html(),
    }
    return render(request, 'customer_list.html', customer)
2. 在html页面文件：
    <div class="table">
        <table class="table table-bordered">
            <tbody>
            {% for item in queryset %}
                <tr row-id="{{ item.id }}">
                    <th scope="row">{{ item.id }}</th>
                    <td>{{ item.username }}</td>
                    ...
                </tr>
            {% endfor %}
            </tbody>
        </table>

        <nav aria-label="Page navigation">
            <ul class="pagination">
                {{ page_html }}
            </ul>
        </nav>
    </div>
"""
import copy

from django.http import QueryDict
from django.utils.safestring import mark_safe


class Pagination:
    def __init__(self, request, queryset, per_page_count=10, page_side_count=4):
        self.request = request
        self.queryset = queryset
        self.per_page_count = per_page_count
        self.item_total = queryset.count()
        page_total, remind = self.item_total.__divmod__(self.per_page_count)
        self.page_total = page_total + int(bool(remind))
        self.page_side_count = page_side_count
        self.page = self.valid_page()
        self.item_start = (self.page - 1) * self.per_page_count
        self.item_end = self.item_start + self.per_page_count

    def valid_page(self):
        page = self.request.GET.get('page')
        if page is None:
            return 1
        if page.isdecimal() is False:
            return 1
        page = int(page)
        if page < 1:
            return 1
        elif page > self.page_total and self.page_total > 0:
            return self.page_total
        else:
            return page

    def html(self):
        if self.page - self.page_side_count < 0:
            page_start = 1
        else:
            page_start = self.page - self.page_side_count
        if self.page + self.page_side_count > self.page_total:
            page_end = self.page_total
        else:
            page_end = self.page + self.page_side_count

        query_dict = copy.deepcopy(self.request.GET)
        page_show_html_list = []
        if page_start > 1:
            query_dict.setlist('page', [1])
            page_show_html_list.append(f'<li><a href="?{query_dict.urlencode()}">首页</a></li>')
            query_dict.setlist('page', [self.page - 1])
            page_show_html_list.append(f'<li><a href="?{query_dict.urlencode()}">上一页</a></li>')

        for i in range(page_start, page_end + 1):
            query_dict.setlist('page', [i])
            if i == self.page:
                page_str = f'<li class="active"><a href="?{query_dict.urlencode()}">{i}</a></li>'
            else:
                page_str = f'<li><a href="?{query_dict.urlencode()}">{i}</a></li>'
            page_show_html_list.append(page_str)

        if page_end < self.page_total:
            query_dict.setlist('page', [self.page + 1])
            page_show_html_list.append(f'<li><a href="?{query_dict.urlencode()}">下一页</a></li>')
            query_dict.setlist('page', [self.page_total])
            page_show_html_list.append(f'<li><a href="?{query_dict.urlencode()}">尾页</a></li>')

        page_show_html_list.append(f'<li class="disabled"><a>共 {self.page_total} 页 {self.item_total} 条</a></li>')
        return mark_safe(''.join(page_show_html_list))

    def sub_queryset(self):
        return self.queryset[self.item_start:self.item_end]
